#Keyword arguments (kwargs)
def tag(name, **kwargs):
    print(name)
    print(kwargs)
    print(type(kwargs))

tag('img', src="monet.jpg", alt="Sunrise by Claude Monet", border=1)
#keyword arguments use dict instead of tuple

#The code will look like this -
def tag(name, **attributes):
    result = '<' + name
    for key, value in attributes.items():
       result += ' {k}="{v}"'.format(k=key, v=str(value))
       result += '>'
    return result

tag('img', src="monet.jpg", alt="Sunrise by Claude Monet", border=1)


#Position
#*args before **kwargs
def print_args(**kwargs, *args): #Will give a syntax error

#Standard args before star-args
def print_args(arg1, arg2, *args):
    print(arg1)
    print(arg2)
    print(args)

print_args(1, 2, 3, 4, 5)

#Anything after *args must be passed using keywords
def print_args(arg1, arg2, *args, kwarg1, kwarg2):
    print(arg1)
    print(arg2)
    print(args)
    print(kwarg1)
    print(kwarg2)

print_args(1, 2, 3, 4, 5, kwarg1=6, kwarg2=7)

print_args(1, 2, 3, 4, 5, 6, 7)
#Will fail as 6 & 7 added to args, not kwarg1 and kwarg2

#**kwargs must be last
def print_args(arg1, arg2, *args, kwarg1, kwarg2, **kwargs):
    print(arg1)
    print(arg2)
    print(args)
    print(kwarg1)
    print(kwarg2)
    print(kwargs)

print_args(1, 2, 3, 4, 5, kwarg1=6, kwarg2=7, kwarg3=8, kwarg4=9)

#parameters after **kwargs results in a syntax error:
def print_args(arg1, arg2, *args, kwarg1, kwarg2, **kwargs, kwargs99):


#Sometimes we want keyword-only arguments
def print_args(arg1, arg2, *, kwarg1, kwarg2):
    print(arg1)
    print(arg2)
    print(kwarg1)
    print(kwarg2)

print_args(1, 2, kwarg1=6, kwarg2=7)

print_args(1, 2, 3, kwarg1=6, kwarg2=7)#Will fail
